﻿using System;
using System.Collections.Generic;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Kiiro.Common.Entities;
using Kiiro.Common.Interfaces;
using Kiiro.Common.Utility;
using Kiiro.ExceptionManagement;
using Kiiro.Model;
using Kiiro.SiteDefinition.ControlTemplates;
using Kiiro.SiteDefinition.MasterPage;

namespace Kiiro.SiteDefinition.Core
{
    /// <summary>
    /// Kiiro Base Page
    /// </summary>
    /// <see cref="http://www.codeproject.com/KB/aspnet/ErrorHandlingASPNET.aspx"/>
    /// <seealso cref="http://aspnetresources.com/articles/CustomErrorPages.aspx"/>
    public class BasePage : Microsoft.SharePoint.WebPartPages.WebPartPage, IPermissions
    {
        #region Properties
        public BasePage DefaultBasePage
        {
            get;
            set;
        }

        public int ItemId
        {
            get
            {
                int itemId = -1;

                if ( ViewState [ "ItemId" ] != null )
                {
                    itemId = ( int ) ViewState [ "ItemId" ];
                }

                return itemId;
            }
            set
            {
                ViewState [ "ItemId" ] = value;
            }
        }

        public Guid SiteCollectionId
        {
            get
            {
                Guid siteCollectionId = default ( Guid );

                if ( ViewState [ "SiteCollectionId" ] != null )
                {
                    siteCollectionId = ( Guid ) ViewState [ "SiteCollectionId" ];
                }

                return siteCollectionId;
            }
            set
            {
                ViewState [ "SiteCollectionId" ] = value;
            }
        }

        public string ServerRelativeUrl
        {
            get
            {
                string serverRelativeUrl = "";

                if ( ViewState [ "ServerRelativeUrl" ] != null )
                {
                    serverRelativeUrl = ( string ) ViewState [ "ServerRelativeUrl" ];
                }

                return serverRelativeUrl;
            }
            set
            {
                ViewState [ "ServerRelativeUrl" ] = value;
            }
        }

        public string PageTitle { get; set; }        

        public User CurrentUser
        {
            get
            {
                User user = new User ( );

                if ( ViewState [ "CurrentUser" ] != null )
                {
                    user = ( User ) ViewState [ "CurrentUser" ];
                }

                return user;
            }
            set
            {
                ViewState [ "CurrentUser" ] = value;
            }
        }

        public KiiroMaster KiiroMaster
        {
            get { return ( KiiroMaster ) Master; }
        } 
        #endregion
        
        public BasePage ( )
        {
            if ( DefaultBasePage == null )
            {
                if ( SPContext.Current != null )
                {
                    if ( SiteCollectionId.ToString ( ) == Guid.Empty.ToString ( ) && SPContext.Current.Site != null )
                        SiteCollectionId = SPContext.Current.Site.ID;

                    if ( string.IsNullOrEmpty ( ServerRelativeUrl ) && SPContext.Current.Web != null )
                        ServerRelativeUrl = SPContext.Current.Web.ServerRelativeUrl.Length > 1 ? SPContext.Current.Web.ServerRelativeUrl : "";

                    if ( CurrentUser == new User ( ) || CurrentUser.Id < 1 && SPContext.Current.Web != null )
                        CurrentUser = UserModel.GetOrCreateUser ( SPContext.Current.Web.CurrentUser.ID, SiteCollectionId, ServerRelativeUrl );
                }

                DefaultBasePage = this;

                if ( !DoesPageHavePermissionsSet )
                    GetPermissionBitsForPage ( );

                GetPermissionBitsForPage ( DefaultBasePage );
            }
        }
        
        internal virtual bool Save ( )
        {
            return true;
        }
        internal virtual void Delete ( )
        {
        }
        internal virtual string Cancel ( )
        {
            return string.Empty;
        }

        protected override void OnLoad ( EventArgs e )
        {
            if ( !string.IsNullOrEmpty ( Request.Params [ "debug" ] ) )
            {
                if ( Request.Params [ "debug" ].ToLower ( ) == "access" )
                    throw new UnauthorizedAccessException ( "Kiiro UnauthorizedAccessException" );
                else if ( Request.Params [ "debug" ].ToLower ( ) == "sp" )
                    throw new SPException ( "Kiiro SPException" );
                else
                    throw new Exception ( "Kiiro Exception" );
            }

            if ( !string.IsNullOrEmpty ( Request.Params [ "id" ] ) )
                ItemId = int.Parse ( Request.Params [ "id" ] );

            if ( SPContext.Current != null )
            {
                if ( SiteCollectionId.ToString ( ) == Guid.Empty.ToString ( ) && SPContext.Current.Site != null )
                    SiteCollectionId = SPContext.Current.Site.ID;

                if ( string.IsNullOrEmpty ( ServerRelativeUrl ) && SPContext.Current.Web != null )
                    ServerRelativeUrl = SPContext.Current.Web.ServerRelativeUrl.Length > 1 ? SPContext.Current.Web.ServerRelativeUrl : "";

                if ( CurrentUser == new User ( ) || CurrentUser.Id < 1 && SPContext.Current.Web != null )
                    CurrentUser = UserModel.GetOrCreateUser ( SPContext.Current.Web.CurrentUser.ID, SiteCollectionId, ServerRelativeUrl );
            }

            if ( !DoesPageHavePermissionsSet )
                GetPermissionBitsForPage ( );

            if ( DefaultBasePage == null )
            {
                DefaultBasePage = new BasePage { SiteCollectionId = SiteCollectionId, ServerRelativeUrl = ServerRelativeUrl, CurrentUser = CurrentUser };
                GetPermissionBitsForPage ( DefaultBasePage );
            }

            base.OnLoad ( e );
        }

        protected override void OnLoadComplete ( EventArgs e )
        {
            base.OnLoadComplete ( e );
            
            // Handle any AJAX requests here
            if ( Request.Params [ Constants.AJAXQueryString.OperationType ] != null )
            {
                AjaxModel.Instance.HandleAjaxRequest ( Request, Response, this, SiteCollectionId, ServerRelativeUrl, CurrentUser );
            }

            if ( SPHelpers.IsPortal ( SiteCollectionId, ServerRelativeUrl ) )
            {
                if ( CurrentUser.Login == Constants.Security.AD_AUTH_USERS_DOMAIN_GROUP_NAME )
                    Response.Redirect ( ServerRelativeUrl + "/_layouts/accessdenied.aspx?Source=" + ServerRelativeUrl );

            }
            else if ( SPHelpers.IsProject ( SiteCollectionId, ServerRelativeUrl ) )
            {
                if ( !CurrentUser.Groups.Contains ( KiiroGroup.PortalOwner ) &&
                     !CurrentUser.Groups.Contains ( KiiroGroup.ProjectOwner ) &&
                     !CurrentUser.Groups.Contains ( KiiroGroup.ProjectMember ) )
                {
                    Response.Redirect ( ServerRelativeUrl + "/_layouts/accessdenied.aspx?Source=" + ServerRelativeUrl );
                }
            }
        }

        public void GetPermissionBitsForPage ( BasePage defaultBasePage )
        {
            // to avoid double tap to permissions model copy this (BasePage) permission bits to defaultBasePage permission bits
            if ( DefaultBasePage != null && !DefaultBasePage.DoesPageHavePermissionsSet )
            {
                if ( DoesPageHavePermissionsSet )
                {
                    DefaultBasePage.PermissionBitsActivity = PermissionBitsActivity;
                    DefaultBasePage.PermissionBitsDiscussions = PermissionBitsDiscussions;
                    DefaultBasePage.PermissionBitsDocuments = PermissionBitsDocuments;
                    DefaultBasePage.PermissionBitsLists = PermissionBitsLists;
                    DefaultBasePage.PermissionBitsProjects = PermissionBitsProjects;
                    DefaultBasePage.PermissionBitsSetup = PermissionBitsSetup;
                    DefaultBasePage.PermissionBitsTeams = PermissionBitsTeams;
                    DefaultBasePage.PermissionBitsUsers = PermissionBitsUsers;
                    DefaultBasePage.PermissionBitsWork = PermissionBitsWork;
                }
                else
                {
                    PermissionsModel.GetGlobalPermissionBitsForCurrentUser (
                       DefaultBasePage, DefaultBasePage.CurrentUser, DefaultBasePage.SiteCollectionId, DefaultBasePage.ServerRelativeUrl );
                }
            }
        }
        
        #region IPermissions Members

        private List<bool> permissionBitsSetup = new List<bool> ( );
        /// <summary>
        /// Setup: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsSetup
        {
            get { return this.permissionBitsSetup; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsSetup.Count > 0 )
                    bits = this.permissionBitsSetup;
                else
                    bits = value;

                this.permissionBitsSetup = bits;
            }
        }

        private List<bool> permissionBitsUser = new List<bool> ( );
        /// <summary>
        /// Users: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsUsers
        {
            get { return this.permissionBitsUser; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsUser.Count > 0 )
                    bits = this.permissionBitsUser;
                else
                    bits = value;

                this.permissionBitsUser = bits;
            }
        }

        private List<bool> permissionBitsProjects = new List<bool> ( );
        /// <summary>
        /// Projects: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsProjects
        {
            get { return this.permissionBitsProjects; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsProjects.Count > 0 )
                    bits = this.permissionBitsProjects;
                else
                    bits = value;

                this.permissionBitsProjects = bits;
            }
        }

        private List<bool> permissionBitsActivity = new List<bool> ( );
        /// <summary>
        /// Activity: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsActivity
        {
            get { return this.permissionBitsActivity; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsActivity.Count > 0 )
                    bits = this.permissionBitsActivity;
                else
                    bits = value;

                this.permissionBitsActivity = bits;
            }
        }

        private List<bool> permissionBitsTeams = new List<bool> ( );
        /// <summary>
        /// Teams: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsTeams
        {
            get { return this.permissionBitsTeams; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsTeams.Count > 0 )
                    bits = this.permissionBitsTeams;
                else
                    bits = value;

                this.permissionBitsTeams = bits;
            }
        }

        private List<bool> permissionBitsWork = new List<bool> ( );
        /// <summary>
        /// Work: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsWork
        {
            get { return this.permissionBitsWork; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsWork.Count > 0 )
                    bits = this.permissionBitsWork;
                else
                    bits = value;

                this.permissionBitsWork = bits;
            }
        }

        private List<bool> permissionBitsDiscussions = new List<bool> ( );
        /// <summary>
        /// Discussions: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsDiscussions
        {
            get { return this.permissionBitsDiscussions; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsDiscussions.Count > 0 )
                    bits = this.permissionBitsDiscussions;
                else
                    bits = value;

                this.permissionBitsDiscussions = bits;
            }
        }

        private List<bool> permissionBitsDocuments = new List<bool> ( );
        /// <summary>
        /// Documents: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsDocuments
        {
            get { return this.permissionBitsDocuments; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsDocuments.Count > 0 )
                    bits = this.permissionBitsDocuments;
                else
                    bits = value;

                this.permissionBitsDocuments = bits;
            }
        }

        private List<bool> permissionBitsLists = new List<bool> ( );
        /// <summary>
        /// Lists: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsLists
        {
            get { return this.permissionBitsLists; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsLists.Count > 0 )
                    bits = this.permissionBitsLists;
                else
                    bits = value;

                this.permissionBitsLists = bits;
            }
        }

        private List<bool> permissionBitsProjectPlanFile = new List<bool> ( );
        /// <summary>
        /// Project Plan File: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsProjectPlanFile
        {
            get { return this.permissionBitsProjectPlanFile; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsProjectPlanFile.Count > 0 )
                    bits = this.permissionBitsProjectPlanFile;
                else
                    bits = value;

                this.permissionBitsProjectPlanFile = bits;
            }
        }

        private List<string> permissionErrorMessages = new List<string> ( );
        /// <summary>
        /// Error messages associated with Permsissions validation
        /// </summary>
        public List<string> PermissionErrorMessages
        {
            get { return this.permissionErrorMessages; }
            set
            {
                List<string> errors = new List<string> ( );

                if ( this.permissionErrorMessages.Count > 0 )
                    errors = this.permissionErrorMessages;
                else
                    errors = value;

                this.permissionErrorMessages = errors;
            }
        }

        private bool keyIsValid = false;
        /// <summary>
        /// Is the License Key Valid?
        /// </summary>
        public bool LicenseKeyIsValid
        {
            get { return this.keyIsValid && this.LicenseKeyErrorMessages.Count == 0; }
            set { this.keyIsValid = value; }
        }

        private List<bool> keyBits = new List<bool> ( );
        /// <summary>
        /// License Key: Key Expired = 0, Project Limit = 1, User Limit = 2
        /// </summary>
        public List<bool> LicenseKeyBits
        {
            get { return this.keyBits; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.keyBits.Count > 0 )
                    bits = this.keyBits;
                else
                    bits = value;

                this.keyBits = bits;
            }
        }

        private List<string> keyErrorMessages = new List<string> ( );
        /// <summary>
        /// Error Messages associated with validation the License Key
        /// </summary>
        public List<string> LicenseKeyErrorMessages
        {
            get { return this.keyErrorMessages; }
        }

        /// <summary>
        /// Constructor Method that sets all the PermissionBits
        /// </summary>
        public void GetPermissionBitsForPage ( )
        {
            PermissionsModel.GetGlobalPermissionBitsForCurrentUser ( this, CurrentUser, SiteCollectionId, ServerRelativeUrl );
        }

        /// <summary>
        /// Are PermissionBits already set?
        /// </summary>
        public bool DoesPageHavePermissionsSet
        {
            get
            {
                return this.PermissionBitsActivity.Count > 0 &&
                  this.PermissionBitsDiscussions.Count > 0 &&
                  this.PermissionBitsDocuments.Count > 0 &&
                  this.PermissionBitsLists.Count > 0 &&
                  this.PermissionBitsProjects.Count > 0 &&
                  this.PermissionBitsSetup.Count > 0 &&
                  this.PermissionBitsTeams.Count > 0 &&
                  this.PermissionBitsUsers.Count > 0 &&
                  this.PermissionBitsWork.Count > 0;
            }
        }

        // Special Case Helpers

        /// <summary>
        /// User Id of User being viewed (base.ItemId)
        /// </summary>
        public int UserId
        {
            get { return this.ItemId; }
        }

        private int authorId = 0;
        /// <summary>
        /// Discussion Author's Kiiro Id
        /// </summary>
        public int AuthorId
        {
            get { return this.authorId; }
            set { this.authorId = value; }
        }

        // Special Cases

        private bool canUserUpdateThemselves = false;
        /// <summary>
        /// Can the Current User Update the User being Displayed?
        /// </summary>
        public bool CanUserUpdateThemselves
        {
            get { return this.canUserUpdateThemselves; }
            set { this.canUserUpdateThemselves = value; }
        }

        private bool canTeamMemberUpdateWork = false;
        /// <summary>
        /// Can Team Member Update Work (checks if from Project Plan)?
        /// </summary>
        public bool CanTeamMemberUpdateWork
        {
            get { return this.canTeamMemberUpdateWork; }
            set { this.canTeamMemberUpdateWork = value; }
        }

        private bool canTeamMemberUpdateDiscussion = false;
        /// <summary>
        /// Can a Team Member/Project Manager Update/Delete Discussion?
        /// </summary>
        public bool CanTeamMemberUpdateDiscussion
        {
            get { return this.canTeamMemberUpdateDiscussion; }
            set { this.canTeamMemberUpdateDiscussion = value; }
        }

        #endregion // IPermissions Members
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.SiteDefinition/12/TEMPLATE/FEATURES/Kiiro.Core/BasePage/BasePage.cs $
 * 
 * 36    2/08/10 5:04p Camerons
 * 
 * 35    1/25/10 1:17p Camerons
 * 
 * 34    1/12/10 12:03p Camerons
 * 
 * 33    1/11/10 11:51a Camerons
 * 
 * 32    1/07/10 12:28p Camerons
 * 
 * 31    1/06/10 12:39p Camerons
 * 
 * 30    12/23/09 3:31p Stefanf
 * 
 * 29    26/11/09 10:35a Camerons
 * 
 * 28    17/11/09 6:46p Camerons
 * 
 * 27    7/11/09 3:50p Camerons
 * 
 * 26    6/11/09 8:55p Camerons
 * 
 * 25    3/11/09 12:49p Camerons
 * 
 * 24    2/11/09 6:22p Camerons
 * 
 * 23    31/10/09 1:20p Camerons
 * 
 * 22    28/10/09 6:09p Camerons
 * 
 * 21    28/10/09 3:13p Camerons
 * 
 * 20    28/10/09 11:01a Camerons
 * 
 * 19    5/10/09 1:56p Camerons
 * Implement re-adding of the guest account code to the PortalProvisioner
 * and UserModel. Enable and disable various UI elements for guest account
 * 
 * 18    30/09/09 1:08p Camerons
 * Implementing UserModel.GetOrCreateUser(). 
 * 
 * 17    22/09/09 6:03p Camerons
 * Code changes to support creating user on demand - version 1.1.x.x
 * 
 * 16    21/09/09 5:06p Shafia
 * 
 * 15    21/09/09 3:30p Camerons
 * First batch of changes for 1.1.x.x - Security groups update
 * 
 * 14    31/08/09 9:42a Shafia
 * changed qs = SPHelpers.EditQueryString(qs, "oldUrl", requestUrl); to qs
 * = SPHelpers.EditQueryString(qs, "Source", requestUrl); in
 * "HandleUnauthorizedAccessException"
 * 
 * 13    17/08/09 11:07a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/
